﻿//#define PIXELSTATS

using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using RayDen.Library.Entity.Interface;
using RayDen.RayEngine;

namespace RayDen.GLPlayground
{

    public class MainWindow : GameWindow
    {
        public string GetPicFileName()
        {
            return string.Format("{0}{1}", Path.GetFileName(config.FrameName), DateTime.UtcNow.Second);
            /*
            try {
                return DateTime.UtcNow.Ticks.ToString();
            }
            catch {
                Random rnd = new Random();
                return ((rnd.Next(1000) + 1) * 1000).ToString();
            }*/
        }

        public MainWindow(IRenderConfig cfg)
            : base(cfg.Width, cfg.Height, new OpenTK.Graphics.GraphicsMode(32, 0, 0, 4))
        {
            config = cfg;
            Keyboard.KeyDown += delegate(object sender, KeyboardKeyEventArgs e)
            {
                if (e.Key == Key.Escape)
                {
                    this.Exit();
                }

                if (e.Key == Key.F1)
                {

                    this.config.SaveImage(config.SavePath + this.GetPicFileName() + ".png");
                }

                if (e.Key == Key.F5)
                {
                    this.config.SaveRawImage(config.SavePath + this.GetPicFileName() + ".exr");
                }

                if (e.Key == Key.F10)
                {
                    var eng = config as RayEngineConfiguration;
                    cfg.GetImagePlane().Reset();
                    eng.NextCamera();
                }

                if (e.Key == Key.F11)
                {
                     var eng = config as RayEngineConfiguration;
                    cfg.GetImagePlane().Reset();
                    eng.PrevCamera();
                }

                if (e.Key == Key.F12)
                {
                    cfg.GetImagePlane().Reset();
                }


                switch (e.Key)                
                {
                    case Key.Number1:
                        config.RunCommand(1);
                        break;

                    case Key.Number2:
                        config.RunCommand(2);
                        break;
                    case Key.Number3:
                        config.RunCommand(3);
                        break;
                    case Key.Number4:
                        config.RunCommand(4);
                        break;
                    case Key.Number5:
                        config.RunCommand(5);
                        break;
                    case Key.Number6:
                        config.RunCommand(6);
                        break;
                    case Key.Number7:
                        config.RunCommand(7);
                        break;
                    case Key.Number8:
                        config.RunCommand(8);
                        break;
                    case Key.Number9:
                        config.RunCommand(9);
                        break;
                    case Key.Number0:
                        config.RunCommand(10);
                        break;
                }

                if ((e.Key == Key.AltLeft || e.Key == Key.AltRight) && (e.Key == Key.Enter || e.Key == Key.KeypadEnter))
                    if (this.WindowState == WindowState.Fullscreen)
                        this.WindowState = WindowState.Normal;
                    else
                        this.WindowState = WindowState.Fullscreen;
            };
        }

        protected override void OnClosed(EventArgs e)
        {
            config.Interrupt();
            base.OnClosed(e);
        }
        protected override void OnLoad(EventArgs e)
        {
            GL.ClearColor(Color.Black);
            pixels = new float[Width * Height * 3];
            config.Start();
        }

        protected override void OnResize(EventArgs e)
        {
            GL.Viewport(0, 0, Width, Height);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0f, Width - 1.0f, 0f, Height - 1.0f, -1f, 1f);
            //GL.Ortho(0f, Width - 1.0f, Height - 1.0f, 0f, -1f, 1f);

            base.OnResize(e);
        }

        public IRenderConfig config;
        int counter = 0;
        private int updates = 100;

        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            //if (config is EthalonRenderConfig) {
            //    config.Start();
            //}
            base.OnUpdateFrame(e);
            var film = config.GetImagePlane();
            if (film != null)
            {
                counter++;
                if (counter >= updates)
                {
                    counter++;
                    film.UpdateScreenBuffer();
                    pixels = film.GetScreenBuffer();
                }
            }
        }

        private float[] pixels;
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            if(pixels == null)
                return;
            GL.Clear(ClearBufferMask.ColorBufferBit);
            
            //var film = config.GetImagePlane();

            //film.UpdateScreenBuffer();
            GL.RasterPos2(0, 0);
            GL.DrawPixels(
                //config.GetImagePlane().Width,
                config.Width,
                config.Height,
                //config.GetImagePlane().Height, 
                PixelFormat.Rgb, PixelType.Float, pixels);
#if PIXELSTATS
            var anyNonBlack = pixels.Count(p => p > 0f);

            this.Title = //this.config.GetStats();
            anyNonBlack.ToString();
#else
            this.Title = this.config.GetStats();
#endif
            this.SwapBuffers();
        }


        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            this.config.Dispose();
        }

      

    }
}
